本篇同步發文於個人網站: A First Set of Refactorings
This article references the chapter 6 ” A First Set of Refactorings ” of Refactoring: Improving the Design of Existing Code (2nd Edition). Author had highlighted many important refactorings in this chapter.
I use .NET C# to practice with these refactorings and upload to Github.
(Photo from Pixabay: https://pixabay.com/illustrations/plumber-repair-tools-pipe-plunger-4427401/ )
Extract Function
Tips
- Redundant logics should be extracted as a function
- A function is best when developers see its naming and understand what it does without looking at its implementation.
- A function usually has few lines of code.
- Sometimes a extracted function is not proper, then transfer it into inline lines.
Examples:
- No Variables Out of Scope
- Using Local Variables
- Reassigning a Local Variable
Github
Inline Function
Tips
- If the indirect call of this function is not required, make it as inline function
- This function has no polymorphism. It means that if this function belongs to a class and subclass uses it, inline function doesn’t work.
Examples:
Github
Extract Variable
Tips
- Some expressions are complex, so use Extract Variable to improve readability.
- Check the target expression has no side-effect before extract it
Examples:
- Static Function
- In a Class
Github
Inline Variable
Tips
- If this variable hinders the nearby refactoring, this variable should be removed.
- Check the right side of the assignment to the variable has no side-effect.
Examples:
int grade = student.Grade;
return (grade >= 60);
// after Inline Variable
return student.Grade >= 60;
Change Function Declaration
Tips
- A good function name increases readability.
- Changing parameters of a function decouple between the modules.
- If an published API should be refactored, then use [deprecated] for the original function. After a period, migrate the old function to the new one and remove the old one.
Examples:
- Renaming a Function (Simple Mechanics)
- Renaming a Function (Migration Mechanics)
- Adding a Paramete
- Changing a Parameter to One of Its Properties
Github
Encapsulate Variable
Tips
- Usually use function to encapsulate access of variables
- For mutable data, if its scope exceeds one function, we encapsulate it.
- If the variable’s value is a record, we can use Encapsulate Record
Examples:
- Simple
- Encapsulating the Value
Github
Rename Variable
Tips
- Good naming increases readability
- If the variable is widely used, we can use Encapsulate Variable
- If this variable is a published variable, we can’t use this refactoring
Examples:
- Encapsulating Variable
- Renaming a Constant
Github
Introduce Parameter Object
Tips
- Use a class to packs the parameters of a function
- Keep these classes as Value Objects (DDD)
- Use Change Function Declaration to create the new class parameter
Examples:
- Change Function Declaration
Github
Combine Functions into Class
Tips
- If some parameter exists in multiple functions, creating a class is a good choice. Move the parameter to class field and reduce parameter of function.
-
Combine Functions into Transform is another choice depending on the context
- Use Encapsulate Record for the previously mentioned parameters. Then use Move Function for those function into a new class.
- We can use Extract Function for the logic processing the record data into the new class.
Examples:
Github
Combine Functions into Transform
Tips
- Transform function loads the original data, then use some functions to get new data and set it the fields of derivation data.
- Comparing with Combine Functions into Class, if some code logic updates the original data, Combine Functions into Class is better.
- In a transform function, first deep copy the loaded original data into result(derivation) data. Finally return this result data.
- If the structure of the result is the same as the original, the transform function uses “Enrich” as prefix naming. If the structure changes, then use “Transform” as prefix naming.
- It’s not recommended for JavaScript to use this refactoring instead of using Combine Functions into Class because of Immutable data
Examples:
Github
Split Phase
Tips
- If some logic concurrently processes 2 different things, then separate it into 2 independent modules.
- Extract the second phase code as a new function. And create an intermediate data structure as the parameter of the new function.
- If some parameters in second phase are used by first phase, then move these parameters into the intermediate data structure.
- Extract the first phase as a function and this function returns the intermediate data structure.
Examples:
Github
Conclusion
This chapter introduces me to a whole clever coding environment! I think I ever did some similar refactorings in my previous projects without so detailed guidelines. If you want to learn detailed motivation and mechanics, study the chapter 6 ” A First Set of Refactorings ” of Refactoring: Improving the Design of Existing Code (2nd Edition). and it improves our programmer’s ability.